home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / PROG_TOO / C027B.ZIP / JAS / OPS.C < prev    next >
Text File  |  1990-03-30  |  4KB  |  182 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15.  
  16. INST itable[] = {
  17. {"b$c$s",    O_LAB,    O_NONE,    S_BW,    "x6$c%0d",    F_PC|F_TXT },
  18. {"",        0,    0,    0,    "",        0 },
  19. {"s$C$s",    O_DST,    O_NONE,    S_B,    "x5$c11%0e",    F_B },
  20. #    include "opcodes.h"
  21. };
  22.  
  23. int ninsts = (sizeof itable) / (sizeof itable[0]);
  24.  
  25. INST *
  26. ifind( token, misc )
  27.     register char *token;
  28.     short *misc;
  29. {
  30.     register int lo = 4;
  31.     register int hi = ninsts-2;
  32.     register int i, d;
  33.     register INST *ip;
  34.  
  35.     while ( lo <= hi ) {
  36.         i = (lo + hi) / 2;
  37.         ip = &itable[i];
  38.         d = icmpare( token, ip->mnemon, misc );
  39.         if ( d == 0 ) {
  40.             INST *jp;
  41.  
  42.             /*
  43.              * find the first item with this mnemonic
  44.              */
  45.             for ( jp = ip-1; ; ip = jp-- ) {
  46.                 if ( *(ip->mnemon) != *(jp->mnemon) ) {
  47.                     break;
  48.                 }
  49.                 if ( strcmp( ip->mnemon, jp->mnemon) ) {
  50.                     break;
  51.                 }
  52.             }
  53.             return ip;
  54.         } else if ( d < 0 ) {
  55.             hi = i-1;
  56.         } else {    /* d > 0 */
  57.             lo = i+1;
  58.         }
  59.     }
  60.  
  61.     /*
  62.      * here is some special stuff for conditional branches and sets
  63.      * which were impractical to put in the standard table
  64.      */
  65.     if ( *token == 'b' ) {
  66.         ip = &itable[0];
  67.         if (! icmpare( token, ip->mnemon, misc ) )
  68.             return ip;
  69.     } else if ( *token == 's' ) {
  70.         ip = &itable[2];
  71.         if (! icmpare( token, ip->mnemon, misc ) )
  72.             return ip;
  73.     }
  74.     return (INST *) NULL;
  75. }
  76.  
  77. int
  78. icmpare( token, mnemon, misc )
  79.     char *token;
  80.     char *mnemon;
  81.     short *misc;
  82. {
  83.     register int i;
  84.     register char *tp, *mp;
  85.  
  86.     *misc = 0;
  87.     for ( tp = token, mp = mnemon; *mp; mp++ ) {
  88.         if ( *mp == '$' ) {
  89.             switch ( *++mp ) {
  90.             case 'c':
  91.                 i = chk_cond( tp, 0, misc );
  92.                 if ( i == 0 )
  93.                     return *tp ? *tp : -1;
  94.                 tp += i-1;
  95.                 break;
  96.             case 'C':
  97.                 i = chk_cond( tp, 1, misc );
  98.                 if ( i == 0 )
  99.                     return *tp ? *tp : -1;
  100.                 tp += i-1;
  101.                 break;
  102.             case 'd':
  103.                 if ( *tp == 'r' )
  104.                     *misc |= 0x00;
  105.                 else if ( *tp == 'l' )
  106.                     *misc |= 0x08;
  107.                 else
  108.                     return *tp ? *tp : -1;
  109.                 break;
  110.             case 's':
  111.                 if ( *tp ) {
  112.                     if ( *tp != '.' )
  113.                         return *tp;
  114.                     switch ( *++tp ) {
  115.                     case 'b':
  116.                         *misc |= 0x01;
  117.                         break;
  118.                     case 'w':
  119.                         *misc |= 0x02;
  120.                         break;
  121.                     case 'l':
  122.                         *misc |= 0x04;
  123.                         break;
  124.                     default:
  125.                         return '.';
  126.                     }
  127.                 }
  128.                 break;
  129.             }
  130.         } else if ( *mp != *tp ) {
  131.             return *tp - *mp;
  132.         }
  133.         if ( *tp )
  134.             tp++;
  135.     }
  136.  
  137.     return *tp;
  138. }
  139.  
  140. struct hcc_bug {
  141.     char cc[3];
  142.     char en;
  143. } cctab[] = {
  144.     { "ra", 0x1 },    /* dbcc start here */
  145.     { "f",  0x1 },
  146.     { "t",  0x0 },
  147.     { "eq", 0x7 },    /* bcc start here */
  148.     { "ne", 0x6 },
  149.     { "ge", 0xC },
  150.     { "gt", 0xE },
  151.     { "le", 0xF },
  152.     { "lt", 0xD },
  153.     { "cc", 0x4 },
  154.     { "hi", 0x2 },
  155.     { "ls", 0x3 },
  156.     { "cs", 0x5 },
  157.     { "hs", 0x4 },
  158.     { "lo", 0x5 },
  159.     { "mi", 0xB },
  160.     { "pl", 0xA },
  161.     { "vc", 0x8 },
  162.     { "vs", 0x9 },
  163.     { "", 0 }
  164. };
  165.  
  166. chk_cond( tp, all, misc )
  167.     register char *tp;
  168.     int all;
  169.     short *misc;
  170. {
  171.     register int i;
  172.  
  173.     i = all ? 0 : 3;
  174.     for ( ; cctab[i].cc[0]; i++ ) {
  175.         if (! strncmp( tp, cctab[i].cc, strlen(cctab[i].cc) ) ) {
  176.             *misc |= ( cctab[i].en << 4 ); 
  177.             return strlen( cctab[i].cc );
  178.         }
  179.     }
  180.     return 0;
  181. }
  182.